#!/bin/sh

# ###################### 脚本变量 ######################
# 检测应用程序名
APP_NAME="td_tunnel_tcp"
# 等待应用程序启动超时时间
TIME_OUT_SEC=5

LOG_ENABLE="on"
# 处理日志的脚本路径
HANDLE_LOG_PATH="./bash/handle_tcp_log.sh"
# HANDLE_LOG_PATH="/bin/script/handle_tcp_log.sh" # 小站用

VRF_NAME=$1
VRF_ID=$(echo $1 | awk -F'vrf' '{print $2}')
VLAN_ID=$VRF_ID
# LOCAL_IP=$(ip -4 addr show vlan$VLAN_ID | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
# LOCAL_IP=$(ip -4 addr show vlan$VLAN_ID | grep inet | awk -F'inet ' '{print $2}' | cut -d' ' -f1 | awk -F'[./]' '{print $1"."$2"."$3"."$4}')
LOCAL_IP=$2
SERVER_IP=$3
SERVER_PORT=$4
LISTEN_PORT=$5
MAX_CONN=$6
NET_MODE=$7
NOW_SYSTEM=""

# ###################### 常量 ####################
TD_SYSTEM="TD_RCST"
LINUX_SYSTEM="LINUX"


# ###################### 辅助函数 ####################
system_check() {
    eval devinfo > /dev/null 2>&1 
    if [ $? = 0 ]; then
        NOW_SYSTEM="$TD_SYSTEM"
    else
        NOW_SYSTEM="$LINUX_SYSTEM"
    fi
}

# ###################### 脚本函数 ######################
# 检查是否有相同参数的实例存在，如果有，则kill掉，保障同一vrf下只有一个实例在运行
check_vrf_is_running() {
    local vrf_id=$1
    local exist_pid_=$2
    if [ -z "$exist_pid_" ]; then
        return 0
    fi
    for pid in $exist_pid_; do
        vrf_id_from_pid=$(cat /proc/$pid/cmdline | tr '\0' ' ' | awk -F'--nf_queue_num ' '{print $2}' | cut -d ' ' -f1)
        if [ $vrf_id_from_pid = $vrf_id ]; then
            # echo "vrf$vrf_id is already running with PID $pid."
            kill $pid
        fi
    done
}

my_pidof() {
    local name=$1
    if [ "$NOW_SYSTEM" = "$TD_SYSTEM" ]; then
        # td系统中: ps -ef查出来的第一列为PID，第二列为用户名
        pid=$(ps -ef | grep -w $name | grep -v grep | awk -F' ' '{print $1}')
    else
        # linux系统中: ps -ef查出来的第二列为PID
        pid=$(ps -ef | grep -w $name | grep -v grep | awk -F' ' '{print $2}')
    fi
    echo $pid
}

# 检查两个字符串数组的差异（s1="aa bb", s2="aa bb cc" -> "cc"）
my_diff_str() {
    local str1=$1
    local str2=$2
    for new_str in $str1; do
        found=0
        for exist_str in $str2; do
            if [ $new_str = $exist_str ]; then
                found=1
                break
            fi
        done
        if [ $found = "0" ]; then
            echo "$new_str"
        fi
    done
}

# ###################### 脚本入口 ######################
# 脚本不能输出除PID值以为的内容到终端，调用脚本的地方会将脚本的输出认为是PID处理，如果输出了其他字符，调用脚本的地方会认为是错误处理。

system_check
# TD系统小站需要打mark数据才能发出
hex_vrf_id=$(printf "%x" $VRF_ID)
iptables -t mangle -nL POSTROUTING -w | grep "$SERVER_IP.*MARK or 0x$hex_vrf_id" > /dev/null 2>&1
if [ $? -ne 0 ]; then
    # echo "add mark for $SERVER_IP in vrf$VRF_ID"
    iptables -t mangle -A POSTROUTING -d $SERVER_IP -j MARK --or-mark $VRF_ID -w
fi
# 关闭TCP连接在空闲时进入慢启动状态的选项
cat /etc/sysctl.conf | grep -E "^[^#]*net.ipv4.tcp_slow_start_after_idle=0" > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "net.ipv4.tcp_slow_start_after_idle=0" >> /etc/sysctl.conf
    sysctl -p
fi
# echo 0 > /proc/sys/net/ipv4/tcp_slow_start_after_idle # 小站用

EXIST_PID=$(my_pidof $APP_NAME)
# 校验当前vrf下是否已经存在实例（如果有，则kill掉）
check_vrf_is_running $VRF_ID $EXIST_PID 
params="--vrf_name $VRF_NAME --mode client --local_ip $LOCAL_IP --max_conn_num $MAX_CONN --host_ip $SERVER_IP --tunnel_srv_port $SERVER_PORT --listen_port $LISTEN_PORT --nf_queue_num $VRF_ID --net_mode $NET_MODE"
# 启动tcp server
run_cmd=""
if [ $LOG_ENABLE = "on" ]; then
    run_cmd="ip vrf exec vrf$VRF_ID bin/$APP_NAME $params | $HANDLE_LOG_PATH tcp_client_vrf$VRF_ID &"
else
    run_cmd="ip vrf exec vrf$VRF_ID bin/$APP_NAME $params > /dev/null &"
fi
# echo $run_cmd
eval $run_cmd

# 校验是否启动成功，并返回PID或错误码
TRY_COUNT=0
NEW_PID=$(my_pidof $APP_NAME)
while [ $TRY_COUNT -lt $TIME_OUT_SEC ]; do
    if [ -z "$NEW_PID" ] || [ "$EXIST_PID" = "$NEW_PID" ]; then
        sleep 1
        TRY_COUNT=$(($TRY_COUNT + 1))
        NEW_PID=$(my_pidof $APP_NAME)
        continue
    else
    new_add_pid=$(my_diff_str "$NEW_PID" "$EXIST_PID")
    if [ -n "$new_add_pid" ]; then
        echo $new_add_pid
    fi
    exit 0
    fi
done
echo "-1"
echo "err! start tcp server failed! please check!"
exit 1
